package encryption

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"fmt"
)

type aesCBCWithNoPadding struct {
	key []byte
	iv  []byte
}

func NewAesCBCWithNoPadding(key, iv []byte) *aesCBCWithNoPadding {
	return &aesCBCWithNoPadding{
		key: key,
		iv:  iv,
	}
}

// AES加密函数
func (a *aesCBCWithNoPadding) Encrypt(plaintext []byte) ([]byte, error) {
	if len(plaintext)%aes.BlockSize != 0 {
		padding := aes.BlockSize - len(plaintext)%aes.BlockSize
		plaintext = append(plaintext, bytes.Repeat([]byte{byte(padding)}, padding)...)
	}

	block, err := aes.NewCipher(a.key)
	if err != nil {
		return nil, err
	}

	//if len(plaintext)%aes.BlockSize != 0 {
	//	return nil, fmt.Errorf("plaintext is not a multiple of the block size")
	//}

	ciphertext := make([]byte, len(plaintext))
	mode := cipher.NewCBCEncrypter(block, a.iv)
	mode.CryptBlocks(ciphertext, plaintext)

	return ciphertext, nil
}

// AES解密函数
func (a *aesCBCWithNoPadding) Decrypt(ciphertext []byte) ([]byte, error) {
	block, err := aes.NewCipher(a.key)
	if err != nil {
		return nil, err
	}

	if len(ciphertext)%aes.BlockSize != 0 {
		return nil, fmt.Errorf("ciphertext is not a multiple of the block size")
	}

	plaintext := make([]byte, len(ciphertext))
	mode := cipher.NewCBCDecrypter(block, a.iv)
	mode.CryptBlocks(plaintext, ciphertext)

	return plaintext, nil
}
